package com.yami.shop.listener;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yami.shop.bean.enums.EsOperationType;
import com.yami.shop.bean.enums.OrderStatus;
import com.yami.shop.bean.event.*;
import com.yami.shop.bean.model.*;
import com.yami.shop.dao.ActivityReceiveRecordMapper;
import com.yami.shop.dao.ProdExtensionMapper;
import com.yami.shop.dao.SkuStockMapper;
import com.yami.shop.service.*;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.Date;
import java.util.List;

@Slf4j
@Component("businessNftResultSuccessListener")
@AllArgsConstructor
public class BusinessNftResultSuccessListener {

    private final ProductService productService;

    private final OrderService orderService;

    private final UserAirdropService userAirdropService;

    private final BusinessNftService businessNftService;

    private final AirdropTaskService airdropTaskService;

    private final BusinessNftRecordService businessNftRecordService;

    private final SkuService skuService;

    private final SkuStockMapper skuStockMapper;

    private final ProdExtensionMapper prodExtensionMapper;

    private final ApplicationEventPublisher eventPublisher;

    private final SkuStockLockService skuStockLockService;

    private final ActivityReceiveRecordMapper activityReceiveRecordMapper;

    /**
     * 空投商品
     *
     * @param event event
     */
    @EventListener(BusinessNftResultSuccessEvent.class)
    @Transactional(rollbackFor = Exception.class)
    public void businessNftResultSuccessListener(BusinessNftResultSuccessEvent event) {
        if (ObjectUtil.isEmpty(event.getOutId())) {
            return;
        }
        // 获取取币业务信息
        BusinessNft businessNft = businessNftService.getOne(new LambdaQueryWrapper<BusinessNft>().eq(BusinessNft::getOutId, event.getOutId()).eq(BusinessNft::getBusinessNftId, event.getBusinessNftId()));
        if (ObjectUtil.isEmpty(businessNft)) {
            return;
        }
        // 查询取币成功的数据
        Long count = businessNftRecordService.count(new LambdaQueryWrapper<BusinessNftRecord>().eq(BusinessNftRecord::getBusinessNftId, businessNft.getBusinessNftId()).eq(BusinessNftRecord::getStatus, 2));
        switch (businessNft.getBusinessType()) {
            // 订单取币业务
            case 0:
                Order newOrder = new Order();
                // 修改订单为已发货状态
                newOrder.setStatus(OrderStatus.SUCCESS.value());
                newOrder.setFinallyTime(new Date());
                newOrder.setDvyTime(new Date());
                newOrder.setUpdateTime(new Date());
                newOrder.setOrderId(Long.valueOf(businessNft.getOutId()));
                orderService.updateById(newOrder);
                // 正式锁定库存，标记为使用状态,扣减库存
                Order order = orderService.getById(Long.valueOf(businessNft.getOutId()));
                skuStockLockService.markerStockUse(Collections.singletonList(order.getOrderNumber()));
                break;
            // 开盲取币业务
            case 1:
                BusinessNftRecord businessNftRecord = businessNftRecordService.getOne(new LambdaQueryWrapper<BusinessNftRecord>().eq(BusinessNftRecord::getBusinessNftId, businessNft.getBusinessNftId()).eq(BusinessNftRecord::getStatus, 2));
                eventPublisher.publishEvent(new OpenBoxSuccessEvent(Long.valueOf(businessNft.getOutId()), Long.valueOf(businessNft.getProdId()), businessNft.getUserId(), businessNftRecord.getDawId()));
                break;
            // 合成取币业务
            case 2:

                break;
            // 零元购业务
            case 4:
                ActivityReceiveRecord activityReceiveRecord = activityReceiveRecordMapper.selectById(Long.valueOf(event.getOutId()));
                activityReceiveRecord.setStatus(1);
                activityReceiveRecord.setUpdateTime(new Date());
                activityReceiveRecordMapper.updateById(activityReceiveRecord);
                skuStockLockService.markerStockUse(Collections.singletonList(activityReceiveRecord.getId().toString()));
                break;
            // 提现空投
            case 5:
                break;
            // 空投取币业务
            case 9:
                // 修改空投记录状态
                UserAirdrop userAirdrop = new UserAirdrop();
                userAirdrop.setAirDropId(Long.valueOf(event.getOutId()));
                userAirdrop.setSuccessNum(count.intValue());
                userAirdrop.setStatus(count.intValue() == businessNft.getNum() ? 2 : 3);
                userAirdrop.setUpdateTime(new Date());
                userAirdropService.updateById(userAirdrop);
                List<Sku> skus = skuService.listSkuAndSkuStock(Long.valueOf(businessNft.getProdId()));
                // 更新sku库存
                Sku sku = skus.get(0);
                sku.setStocks(count.intValue());
                skuStockMapper.updateStocks(sku);
                skuService.removeSkuCacheBySkuId(sku.getSkuId(), sku.getProdId());
                productService.removeProdCacheByProdId(sku.getProdId());
                // 更新商品库存
                prodExtensionMapper.updateProdStocks(Long.valueOf(businessNft.getProdId()));
                // 更新es中的商品库存
                eventPublisher.publishEvent(new EsProductUpdateEvent(sku.getProdId(), null, EsOperationType.UPDATE));
                // 修改商品售罄状态
                eventPublisher.publishEvent(new ProdStockChangeStatusEvent(Long.parseLong(businessNft.getProdId()), sku.getSkuId()));

                UserAirdrop userAirdropServiceById = userAirdropService.getById(Long.valueOf(event.getOutId()));
                // 任务空投
                if (ObjectUtil.isNotEmpty(userAirdropServiceById) && userAirdropServiceById.getBusinessType() == 2 && ObjectUtil.isNotNull(userAirdropServiceById.getAirdropBusinessId())) {
                    AirdropTask airdropTask = new AirdropTask();
                    airdropTask.setAirdropTaskId(userAirdropServiceById.getAirdropBusinessId());
                    airdropTask.setSuccessNum(count.intValue());
                    airdropTask.setUpdateTime(new Date());
                    airdropTaskService.updateById(airdropTask);
                }
                // 空投权益券系统自动空投完成之后通知权益服务处理权益券状态
                if (ObjectUtil.isNotEmpty(userAirdropServiceById) && userAirdropServiceById.getBusinessType() == 3 && ObjectUtil.isNotNull(userAirdropServiceById.getAirdropBusinessId())) {
                    Long waitNum = userAirdropService.count(new LambdaQueryWrapper<UserAirdrop>().eq(UserAirdrop::getAirdropBusinessId, userAirdropServiceById.getAirdropBusinessId()).and(wrapper -> wrapper.eq(UserAirdrop::getStatus, 0).or().eq(UserAirdrop::getStatus, userAirdropServiceById.getBusinessType())));
                    if (waitNum < 1) {
                        eventPublisher.publishEvent(new KtVerificationRightsEvent(2L,userAirdropServiceById.getAirdropBusinessId()));
                    }
                }
                // 空投邀请、拉新奖励后通知上游服务，修改奖励发放状态
                if (ObjectUtil.isNotEmpty(userAirdropServiceById) && userAirdropServiceById.getBusinessType() == 4 && ObjectUtil.isNotNull(userAirdropServiceById.getAirdropBusinessId())) {
                    Long waitNum = userAirdropService.count(new LambdaQueryWrapper<UserAirdrop>().eq(UserAirdrop::getAirdropBusinessId, userAirdropServiceById.getAirdropBusinessId()).and(wrapper -> wrapper.eq(UserAirdrop::getStatus, 0).or().eq(UserAirdrop::getStatus, userAirdropServiceById.getBusinessType())));
                    if (waitNum < 1) {
                        eventPublisher.publishEvent(new GrantEvent(userAirdropServiceById.getAirdropBusinessId(),1));
                    }
                }
                break;
            case 10:
                break;
            case 11:
                break;
            default:
        }
    }
}
